volatile[ /ˈvɑː.lə.t̬əl/]
volatile int i = 10;
volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素(操作系统、硬件、其它线程等)更改。所以使用 volatile 告诉编译器不应对这样的对象进行优化。
volatile 关键字声明的变量,每次访问时都必须从内存中取出值(没有被 volatile 修饰的变量,可能由于编译器的优化,从 CPU 寄存器中取值)
const 可以是 volatile (如只读的状态寄存器)
指针可以是 volatile
volatile跟const类似可以跟指针,引用等组合
带有volatile的成员函数只能被volatile的对象调用。
- 合成的拷贝对volatile对象无效
如果没有定义复制构造函数,编译器会自动合成一个。与合成的默认构造函数不同,即使我们定义了其他构造函数,也会合成复制构造函数。合成复制构造函数会对成员逐个进行初始化,将新对象初始化为原对象的副本。
合成的成员接受的形参类型是常量(非 volatile)引用,以此不能把一个非volatile引用绑定到一个volatile,因此需要自定义。
class Foo
{
public:
//从一个volatile对象进行拷贝
Foo(const volatile Foo&);
//将一个volatile对象赋值给一个*非*Volatile对象
Foo& operator=(volatile const Foo&);
//将一个volatile对象赋值给一个volatile对象
//这个没问题volatile表示这个函数只能被volatile对象调用,而这是个符号重载,所以左值一定是volatile类型
Foo& operator=(volatile const Foo&) volatile;
//Foo类的其他部分//
}
注意与java等其他语言的volatile作区别
- volatile 不能解决多线程中的问题。
- 按照 Hans Boehm & Nick Maclaren 的总结,volatile 只在三种场合下是合适的。
- 和信号处理(signal handler)相关的场合;
- 和内存映射硬件(memory mapped hardware)相关的场合;
- 和非本地跳转(setjmp 和 longjmp)相关的场合。
- 谈谈 C/C++ 中的 volatile
要注意C/C++的volatile无法解决多线程问题